using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
#if UNITY_ANDROID && !UNITY_EDITOR
using UnityEngine.Android;
#endif

public class AndroidHelper : MonoBehaviour {


	static GameObject obj = null;
	static System.Action escapeCallback;
	static Action<string> onGetOAIDCallback;

	static AndroidHelper () {
		if (obj == null) {
			try {
				obj = new GameObject (typeof (AndroidHelper).Name);
				GameObject.DontDestroyOnLoad (obj);
				obj.AddComponent<AndroidHelper> ();
			} catch (System.Exception e) {
				Debug.LogException (e);
			}
		}
	}





	class PermissionRequstInfo
	{
		public List<Action> requestCallbacks = new List<Action>();
		public float waitTime = 2f;
	}

	static Dictionary<string, PermissionRequstInfo> requestPermissionDic = new Dictionary<string, PermissionRequstInfo>();


	public static void RequestAndroidPermission (string permission, System.Action callback) {
        #if UNITY_ANDROID && !UNITY_EDITOR
		//已存在权限
		if (Permission.HasUserAuthorizedPermission(permission))
		{
			callback?.Invoke();
			return;
		}
		//已在请求中
		if (requestPermissionDic.ContainsKey(permission))
		{
			requestPermissionDic[permission].requestCallbacks.Add(callback);
		}
		//创建注册请求
		else
		{
			PermissionRequstInfo requestInfo = new PermissionRequstInfo();
			requestPermissionDic[permission] = requestInfo;
			requestInfo.requestCallbacks.Add(callback);
			Permission.RequestUserPermission(permission);
		}
        #endif

	}
	public static void UnrequestAndroidPermission(string permission, System.Action callback)
	{
        #if UNITY_ANDROID && !UNITY_EDITOR
		//反注册请求
		if (requestPermissionDic.ContainsKey(permission))
		{
			requestPermissionDic[permission].requestCallbacks.Remove(callback);
		}
        #endif
	}

	public static int GetSDKInt()
	{
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<int> ("GetSDKInt", new object[] { });
#else
		return 0;
#endif
	}


	void Update ()
	{
#if UNITY_ANDROID && !UNITY_EDITOR
		List<string> toDelete = new List<string>();
		foreach (var info in requestPermissionDic)
		{
			// 到时间后未获取到权限
			if (info.Value.waitTime < 0)
			{
				toDelete.Add(info.Key);
			}
			else
			{
				info.Value.waitTime -= Time.deltaTime;
				// 已获取到权限
				if (Permission.HasUserAuthorizedPermission(info.Key))
				{
					foreach (var requestCallback in info.Value.requestCallbacks)
					{
						if (requestCallback != null)
						{
							requestCallback();
						}
					}
					toDelete.Add(info.Key);
				}
			}
		}
		//反注册超时与获取到的权限
		foreach (var permission in toDelete)
		{
			PermissionRequstInfo info = requestPermissionDic[permission];
			foreach (var requestCallback in info.requestCallbacks)
			{
				if (requestCallback != null)
				{
					requestCallback();
				}
			}
			requestPermissionDic.Remove(permission);
		}
#endif
	}

	public static string GetChannel () {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<string> ("getChannel", new object[] { });
#else
		return null;
#endif
	}

	public static string GetOAID()
	{
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<string> ("GetOAID", new object[] { });
#else
		return "";
#endif
	}

	// 获取安卓IMEI
	public static string GetIMEI()
	{
#if UNITY_ANDROID && !UNITY_EDITOR
		if (Permission.HasUserAuthorizedPermission("android.permission.READ_PHONE_STATE"))
		{
			try
			{
				AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
				AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
				var telephoneyManager = jo.Call<AndroidJavaObject>("getSystemService", "phone");
				string imei = telephoneyManager.Call<string>("getImei", 0);
				if (imei == null)
				{
					imei = "";
				}
				return imei;
			}
			catch(Exception e)
			{
				Debug.LogError("Permission IMEI Get Failed!");
				Debug.LogError(e);
				return "";
			}
		}
		else
		{
			return "";
		}
#else
		return "";
#endif
	}


#region 头条广告SDK


	 //内置事件: “注册” ，属性：注册方式，是否成功，属性值为：wechat ，true
    public static void OnEventRegister(string method, bool isSuccess)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		jo.Call("OnEventRegister", new object[] {method, isSuccess});
#endif
    }

	//内置事件 “支付”，属性：商品类型，商品名称，商品ID，商品数量，支付渠道，币种，是否成功（必传），金额（必传）
    public static void OnEventPurchase(string contentType, string contentName, string contentId, int contentNum, string paymentChannel, string currency, bool isSuccess, int currencyAmount)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		jo.Call("OnEventPurchase", new object[] {contentType, contentName, contentId, contentNum, paymentChannel, currency, isSuccess, currencyAmount});
#endif
    }

	 //登录
    public static void OnEventLogin(string method, bool isSuccess)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		jo.Call("OnEventLogin", new object[] {method, isSuccess});
#endif
    }

	 //自定义埋点
    public void OnCustomEvent(string eventName, string jsonStr)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		jo.Call("OnCustomEvent", new object[] {eventName, jsonStr});
#endif
    }

#endregion


	public static void SetEscapeCallback (System.Action escapeCallback) {
		AndroidHelper.escapeCallback = escapeCallback;

#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");

		if (escapeCallback != null) {
			jo.Call ("setOnBackPressedCallback", new object[] { typeof (AndroidHelper).Name, "OnEscape" });
		} else {
			jo.Call ("setOnBackPressedCallback", new object[] { null, null });
		}
#endif
	}

	

	public static void MoveTaskToBack () {
		AndroidHelper.escapeCallback = escapeCallback;

#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		jo.Call<bool> ("moveTaskToBack", new object[] { false });
#endif
	}
	
	public static bool isIl2cpp () {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<bool> ("isIl2cpp", new object[] { });
#else
		return false;
#endif
	}
	
	public static int GetVersionNumber () {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<int> ("GetVersionNumber", new object[] { });
#else
		return 0;
#endif
	}
	
	public static string GetIl2cppPatchResourceCachePath () {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<string> ("GetIl2cppPatchResourceCachePath", new object[] { });
#else
		return null;
#endif
	}
	
	public static string GetIl2cppPatchCachePath () {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<string> ("GetIl2cppPatchCachePath", new object[] { });
#else
		return null;
#endif
	}
	
	public static string GetIl2cppPatchMd5 () {
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<string> ("GetIl2cppPatchMd5", new object[] { });
#else
		return null;
#endif
	}
	
	public static bool SaveIl2cppPatchConfig (string savePath, string md5, int version, int minAppVersion)
	{
#if UNITY_ANDROID && !UNITY_EDITOR
		AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
		AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject> ("currentActivity");
		return jo.Call<bool> ("SaveIl2cppPatchConfig", new object[] {savePath, md5, version, minAppVersion});
#else
		return false;
#endif
	}
	
	void OnEscape (string param) {
		if (AndroidHelper.escapeCallback != null) {
			AndroidHelper.escapeCallback ();
		}
	}

	public void OnGetOAID(string msg)
	{
		onGetOAIDCallback?.Invoke(msg);
		onGetOAIDCallback = null;
	}
}